﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace NugetPublishWizard.Models
{
    [Serializable]
    public class NugetPackageMetaData : IDataErrorInfo
    {
        private string _lastError = string.Empty;

        /// <summary>
        /// Required! The unique identifier for the package. This is the package name that is shown when packages are listed and which you enter in PowerShell commands such as Install-Package. Package IDs may not contain any spaces or characters that are invalid in an URL. In general, they follow the same rules as .NET namespaces do. So “Foo.Bar” is a valid ID, “Foo!” and “Foo Bar” are not.
        /// </summary>
        [Required]
        public string Id { get; set; }
        /// <summary>
        /// Required! The version of the package, in a format like 1.2.3.
        /// </summary>
        [Required]
        public string Version { get; set; }
        /// <summary>
        /// The human-friendly title of the package.
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// Required! A comma-separated list of authors of the package code.
        /// </summary>
        [Required]
        public List<string> Authors { get; set; }
        /// <summary>
        /// A comma-separated list of the package creators. This is often the same list as in authors.
        /// </summary>
        public List<string> Owners { get; set; }
        /// <summary>
        /// Required! A description of the package.
        /// </summary>
        [Required]
        public string Description { get; set; }
        /// <summary>
        /// A summary of the package.
        /// </summary>
        public string Summary { get; set; }
        /// <summary>
        /// The locale ID for the package, such as en-us.
        /// </summary>
        public CultureInfo Language { get; set; }
        /// <summary>
        /// A URL for the home page of the package.
        /// </summary>
        public string ProjectUrl { get; set; }
        /// <summary>
        /// A URL for the image to use as the icon for the package in the Add Library Package Reference dialog box. This should be a 32x32-pixel .png file that has a transparent background.
        /// </summary>
        public string IconUrl { get; set; }
        /// <summary>
        /// A link to the license that the package is under.
        /// </summary>
        public string LicenseUrl { get; set; }
        /// <summary>
        /// A Boolean value that specifies whether the client needs to ensure that the package license (described by licenseUrl) is accepted before the package is installed.
        /// </summary>
        public bool RequireLicenseAcceptance { get; set; }
        /// <summary>
        /// The list of dependencies for the package. For more information, see Specifying Dependencies later in this document.
        /// </summary>
        public List<NugetDependencie> Dependencies { get; set; }
        /// <summary>
        /// A space-delimited list of tags and keywords that describe the package. This information is used to help make sure users can find the package using searches in the Add Package Reference dialog box or filtering in the Package Manager Console window.
        /// </summary>
        public List<string> Tags { get; set; }

        public string this[string columnName]
        {
            get
            {
                _lastError = string.Empty;
                switch (columnName)
                {
                    case "Id":
                        if (String.IsNullOrEmpty(Id))
                            _lastError = "Please insert a id!";
                        Id = Id.Trim();
                        if (!IsValidId(Id))
                            _lastError = "Please insert valid a id!";
                        break;
                    case "Version":
                        System.Version v;
                        if (String.IsNullOrEmpty(Version) || !System.Version.TryParse(Version, out v))
                            _lastError = "Please insert a version!";
                        break;
                    case "Description":
                        if (String.IsNullOrEmpty(Description))
                            _lastError = "Please insert a description!";
                        break;
                    case "ProjectUrl":
                        if (!String.IsNullOrEmpty(ProjectUrl))
                        {
                            try
                            {
                                this.ProjectUrl = new Uri(this.ProjectUrl).ToString();
                            }
                            catch (Exception ex)
                            {
                                _lastError = ex.Message;
                            }
                        }
                        break;
                    case "LicenseUrl":
                        if (!String.IsNullOrEmpty(LicenseUrl))
                        {
                            try
                            {
                                this.LicenseUrl = new Uri(this.LicenseUrl).ToString();
                            }
                            catch (Exception ex)
                            {
                                _lastError = ex.Message;
                            }
                        }
                        break;
                    case "IconUrl":
                        if (!String.IsNullOrEmpty(IconUrl))
                        {
                            try
                            {
                                this.IconUrl = new Uri(this.IconUrl).ToString();
                            }
                            catch (Exception ex)
                            {
                                _lastError = ex.Message;
                            }
                        }
                        break;
                    case "RequireLicenseAcceptance":
                        if (this.RequireLicenseAcceptance &&
                            string.IsNullOrEmpty(this.LicenseUrl))
                        {
                            _lastError = "Please provide a license url";
                        }
                        break;
                    default: _lastError = "";
                        break;

                }
                return _lastError;
            }
        }

        public string GetBuildSummary()
        {
            StringBuilder result = new StringBuilder();

            result.AppendLine(string.Format("Package Id: {0}", this.Id));
            result.AppendLine(string.Format("Version: {0}", this.Version));
            result.AppendLine(string.Format("Authors: {0}", Helper.ListToString(this.Authors, ',')));
            if (this.IconUrl != string.Empty)
                result.AppendLine(string.Format("IconUrl: {0}", this.IconUrl));
            if (this.ProjectUrl != string.Empty)
                result.AppendLine(string.Format("ProjectUrl: {0}", this.ProjectUrl));
            if (this.LicenseUrl != string.Empty)
            {
                result.AppendLine(string.Format("LicenseUrl: {0}", this.LicenseUrl));
                result.AppendLine(string.Format("RequireLicenseAcceptance: {0}", this.RequireLicenseAcceptance));
            }
            result.AppendLine(string.Format("Language: {0} ({1})", this.Language.EnglishName, this.Language.Name));

            if (this.Owners.Count != 0)
                result.AppendLine(string.Format("Owners: {0}", Helper.ListToString(this.Owners, ',')));
            if (this.Tags.Count != 0)
                result.AppendLine(string.Format("Tags: {0}", Helper.ListToString(this.Tags, ' ')));

            result.AppendLine();
            result.AppendLine("Description");
            result.AppendLine("--------------------------------------------------------------------");
            result.AppendLine(this.Description);
            result.AppendLine("--------------------------------------------------------------------");
            if (this.Dependencies.Count != 0)
            {
                result.AppendLine();
                result.AppendLine("Dependencies");
                result.AppendLine("--------------------------------------------------------------------");
                foreach (NugetDependencie dep in this.Dependencies)
                    result.AppendLine(dep.ToString());
                result.AppendLine("--------------------------------------------------------------------");
            }
            if (this.Summary != null && this.Summary.ToString() != string.Empty)
            {
                result.AppendLine();
                result.AppendLine("Summary");
                result.AppendLine("--------------------------------------------------------------------");
                result.AppendLine(this.Summary);
                result.AppendLine("--------------------------------------------------------------------");
            }

            return result.ToString();
        }

        public static bool IsValidId(string id)
        {
            return Regex.Match(id, "^[a-zA-Z0-9.]*$").Success;
        }

        #region IDataErrorInfo Member

        public string Error
        {
            get { return _lastError; }
        }

        #endregion
    }
}
